<template>
  <div>
    <DaprPlusTable
      :table-title="$t('daprplus.auth.user.list')"
      :entity="entity"
      :grid-options="gridOptions"
      :form-options="formOptions"
      :query-api="crudApi.getPage"
      :create-api="crudApi.create"
      :update-api="crudApi.update"
      :delete-api="crudApi.delete"
      :default-new-record="createDefaultUser"
      @update:grid-api="onGridApiUpdate"
    >
      <template #action="{ row }">
        <AccessControl :codes="[`${entity.code}:SetRole`]" type="code">
          <Button type="link" @click="handleSetRole(row)">
            <template #icon><TeamOutlined /></template>
            {{ $t('daprplus.auth.user.role') }}
          </Button>
        </AccessControl>
        <Dropdown>
          <Button type="link" class="more-btn">
            <EllipsisOutlined style="font-size: 18px" />
          </Button>
          <template #overlay>
            <Menu>
              <Menu.Item @click="handleSetPassword(row)">
                <LockOutlined />
                <span style="margin-left: 8px">{{
                  $t('daprplus.auth.user.setPassword')
                }}</span>
              </Menu.Item>
            </Menu>
          </template>
        </Dropdown>
      </template>
    </DaprPlusTable>
    <SetPasswordModal v-model:open="passwordModalOpen" :user="currentUser" />
    <SetRoleModal v-model:open="roleModalOpen" :user="currentUser" />
  </div>
</template>

<script lang="ts" setup>
import type { ExtendedVxeGridApi, VxeGridProps } from '#/adapter/vxe-table';
import type { VbenFormProps } from '#/adapter/form';
import { DaprPlusTable } from '#/components/daprplus';
import { createBooleanColumn } from '#/utils/daprplus';
import { createCrudApi } from '#/api/daprplus';
import type { IOutDto, IInDto, EntityInfo } from '#/utils/daprplus';
import { Button, Dropdown, Menu } from 'ant-design-vue';
import {
  LockOutlined,
  TeamOutlined,
  EllipsisOutlined,
} from '@ant-design/icons-vue';
import { ref } from 'vue';
import SetPasswordModal from './SetPasswordModal.vue';
import SetRoleModal from './SetRoleModal.vue';
import { $t } from '#/locales';
import { AccessControl } from '@vben/access';

const baseUrl = '/identity/api/user';
const crudApi = createCrudApi<UserInDto, UserOutDto>(baseUrl);

const entity: EntityInfo = {
  code: 'User',
  display: $t('daprplus.auth.user.title'),
};

// 配置搜索表单
const formOptions: VbenFormProps = {
  collapsed: false,
  schema: [
    {
      component: 'Input',
      label: '用户名',
      fieldName: 'userName',
    },
    {
      component: 'Input',
      label: '昵称',
      fieldName: 'nickName',
    },
    {
      component: 'Input',
      label: '邮箱',
      fieldName: 'email',
    },
    {
      component: 'Input',
      label: '手机号',
      fieldName: 'phoneNumber',
    },
    {
      component: 'VbenCheckbox',
      label: '双因素',
      fieldName: 'twoFactorEnabled',
    },
    {
      component: 'VbenCheckbox',
      label: '已锁定',
      fieldName: 'isLocked',
    },
  ],
  showCollapseButton: true,
  submitOnChange: true,
};

// 验证规则
const validRules = {
  userName: [
    { required: true, message: '用户名不能为空' },
    { min: 2, max: 50, message: '用户名长度应在2-50个字符之间' },
  ],
  email: [
    {
      validator: (params: any) => {
        const value = params.value;
        if (!value) return;
        if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
          return new Error('请输入有效的邮箱地址');
        }
      },
    },
  ],
  phoneNumber: [
    {
      validator: (params: any) => {
        const value = params.value;
        if (!value) return;
        if (!/^1[3-9]\d{9}$/.test(value)) {
          return new Error('请输入有效的手机号码');
        }
      },
    },
  ],
};

// 扩展配置
const gridOptions: VxeGridProps<UserOutDto> = {
  editRules: validRules,
  columns: [
    { type: 'checkbox', width: 40 },
    {
      field: 'id',
      title: '编号',
      sortable: true,
      width: 130,
    },
    {
      field: 'userName',
      title: '用户名',
      sortable: true,
      align: 'left',
      minWidth: 120,
      editRender: { name: 'input' },
    },
    {
      field: 'nickName',
      title: '昵称',
      align: 'left',
      minWidth: 120,
      editRender: { name: 'input' },
    },
    {
      field: 'email',
      title: '邮箱',
      align: 'left',
      minWidth: 120,
      editRender: { name: 'input' },
    },
    createBooleanColumn('emailConfirmed', '邮箱验证'),
    {
      field: 'phoneNumber',
      title: '手机号',
      align: 'left',
      minWidth: 120,
      visible: false,
      editRender: { name: 'input' },
    },
    createBooleanColumn('phoneNumberConfirmed', '手机验证', { visible: false }),
    createBooleanColumn('isLocked', '已锁定', { width: 100 }),
    createBooleanColumn('twoFactorEnabled', '双因素', {
      width: 100,
      visible: false,
    }),
    {
      field: 'lockoutEnd',
      title: '锁定时间',
      formatter: 'formatDateTime',
      width: 150,
      editRender: { name: 'VxeDatePicker', props: { type: 'datetime' } },
    },
    createBooleanColumn('lockoutEnabled', '登录锁', { width: 130 }),
    {
      field: 'accessFailedCount',
      title: '登录失败',
      width: 90,
    },
    {
      field: 'createdTime',
      title: '创建时间',
      formatter: 'formatDateTime',
      width: 150,
    },
    {
      field: 'operate',
      title: '操作',
      width: 150,
      slots: { default: 'action' },
      fixed: 'right',
    },
  ],
};

let gridApi: ExtendedVxeGridApi;

function onGridApiUpdate(api: ExtendedVxeGridApi) {
  gridApi = api;
}

function createDefaultUser(): UserInDto {
  return {
    id: '0',
    userName: 'user00',
    nickName: '用户00',
    email: undefined,
    emailConfirmed: false,
    phoneNumber: undefined,
    phoneNumberConfirmed: false,
    twoFactorEnabled: false,
    lockoutEnd: null,
    lockoutEnabled: false,
    accessFailedCount: 0,
    isLocked: false,
  };
}

// 密码设置相关
const passwordModalOpen = ref(false);
const roleModalOpen = ref(false);
const currentUser = ref<UserOutDto>();

// 处理设置密码按钮点击
function handleSetPassword(row: UserOutDto) {
  if (row && row.id) {
    currentUser.value = row;
    passwordModalOpen.value = true;
  }
}

// 处理设置角色按钮点击
function handleSetRole(row: UserOutDto) {
  if (row && row.id) {
    currentUser.value = row;
    roleModalOpen.value = true;
  }
}

export interface UserOutDto extends IOutDto {
  accessFailedCount?: number;
  createdTime?: Date;
  email?: null | string;
  emailConfirmed?: boolean;
  isLocked?: boolean;
  isSystem?: boolean;
  lockoutEnabled?: boolean;
  lockoutEnd?: Date | null;
  nickName?: null | string;
  phoneNumber?: null | string;
  phoneNumberConfirmed?: boolean;
  twoFactorEnabled?: boolean;
  userName?: string;
}

export interface UserInDto extends IInDto {
  userName: string;
  password?: string;
  nickName?: string;
  email?: string;
  emailConfirmed: boolean;
  phoneNumber?: string;
  phoneNumberConfirmed: boolean;
  twoFactorEnabled: boolean;
  lockoutEnd?: Date | null;
  lockoutEnabled: boolean;
  accessFailedCount: number;
  isLocked: boolean;
}
</script>

<style scoped>
.more-btn {
  padding: 0 8px;
  margin-left: -8px;
}
</style>
